//---------------------------------------------------------------------------
//
// Name:        DeadProxyApp.cpp
// Author:      Carl Chatfield
// Created:     1/5/2008 6:48:54 PM
// Description: 
//
//---------------------------------------------------------------------------

#include "DeadProxyApp.h"



IMPLEMENT_APP(DeadProxyFrmApp)


DeadProxyFrmApp * app;

bool DeadProxyFrmApp::OnInit()
{
    app = this;
    CManager = new ClientManager();
    wxFileConfig *pConfig = new wxFileConfig("","","testing.conf","",wxCONFIG_USE_LOCAL_FILE);
    
    if(!RunLocateClientDlg())
    {
        return true;
    }
    wxString * DatFileName = new wxString(ClientDirectory);
    DatFileName->Append(wxT("\\Tibia.dat"));
    DataReader = new DatReader(DatFileName);
    DataReader->LoadDatFile();
    
    wxString * SprFilePath = new wxString(ClientDirectory);
    SprFilePath->Append(wxT("\\Tibia.spr"));
    SpriteReader = new SprReader(SprFilePath);
    
    delete SprFilePath;
    frame = new DeadProxyFrm(NULL);
    SetTopWindow(frame);
    
    Network = new NetworkHandler();
    Network->InitWinsock();
    Network->InitServers();
    
    wxInitAllImageHandlers();
    
    frame->Show();
    return true;
    

}
 
int DeadProxyFrmApp::OnExit()
{
    CloseAllHandles();
	return 0;
}

void DeadProxyFrmApp::CloseAllHandles()
{
    wxString output;
    int len = CManager->GetCount();
    int i;
    HandleCloser HC;
    for(i = 0; i < len; i++)
    {
        HC.Close(CManager->GetClientByPos(i)->GetHandle());
    }
}

bool DeadProxyFrmApp::RunLocateClientDlg()
{
    wxFileDialog * OpenFileDialog = new wxFileDialog(NULL, wxT("Please Locate A v8.10 Tibia Client"), wxEmptyString, wxEmptyString, wxT("Tibia.exe (Tibia.exe)|Tibia.exe"),wxFD_OPEN, wxDefaultPosition);
    int version;
    VersionGetter CheckVersion;
    wxString errormsg;
    while(true)
    {
        if (OpenFileDialog->ShowModal() == wxID_OK)
        {
            ClientFullPath = OpenFileDialog->GetPath();
            ClientDirectory = OpenFileDialog->GetDirectory();
        } else {
            delete OpenFileDialog;
            return false;
        }
        version = CheckVersion.GetVersion(ClientFullPath.c_str());
        if(version == (8 << 16 | 1))
        {
            delete OpenFileDialog;
            return true;
        } else {
            errormsg.Printf("This Client is version %i.%i", version >> 16, version & 0x0000FFFF);
            wxMessageBox(errormsg, wxT("Wrong Client Version"));
        }
    }
}
    

void DeadProxyFrmApp::TestFunc()
{
//    VersionGetter test;
//    if(test.GetVersion("C:\\Program Files\\Tibia\\Tibia.exe") == (8 << 16 | 1))
//    {
//        wxMessageBox(wxT("Great Success"));
//    }
    //wxString * test = new wxString(wxT("Send: 5000 bytes"));
    //UpdatePacketBox(test, 0, 0);
//    DeadProxyFrm * testfrm = new DeadProxyFrm(NULL);
//    testfrm->Show();
//    wxSleep(10);
    ClientEvent * testevt = new ClientEvent(1);
    CManager->PostEventToClient(0, testevt);
//    ClientEvent * spam = new ClientEvent(CE_GET_PACKET_STRING);
//    spam->SetParam1(1);
//    CManager->PostEventToClient(0, spam);
//    wxArrayString * testas = new wxArrayString;
//    testas->Add("1");
//    testas->Add("2");
//    testas->Add("3");
//    testas->Add("4");
//    testas->Add("5");
//    testas->Add("6");
//    testas->Add("7");
//    wxArrayString * testmi = new wxArrayString;
//    testmi->Add("Bob");
//    testmi->Add("Player Hater");
//    testmi->Add("T - 10");
//    testmi->Add("Is Your Uncle");
//    SetMessageInfo(testmi);
//    SetMessageBoxArray(testas);
//    SpriteReader->GetSprite(1);
}

void DeadProxyFrmApp::LaunchClient()
{
    wxString command(ClientFullPath);
    command.Prepend(wxT("\""));
    command.Append(wxT("\""));
    LaunchClientThread * testLaunchClient = new LaunchClientThread(command.c_str(), ClientDirectory.c_str());
    testLaunchClient->Create();
    testLaunchClient->Run();
}

void DeadProxyFrmApp::AddClient(int pid, void* handle, bool isStandAlone)
{
    wxString * id = new wxString;
    id->Printf("%i:Unknown", pid);
    CManager->AddClient(pid, handle, isStandAlone);
    AddClientToBox(id);
}

void DeadProxyFrmApp::RemoveClient(int pid)
{
    int pos = CManager->GetPosByPid(pid);
    if(pos != -1)
    {
        CManager->RemoveClient(pos);
        RemoveClientFromBox(pos);
    }
}
    

void DeadProxyFrmApp::LogMessage(wxString * output)
{
    ////Please Note, wxWidgets recommends only the main thread access the GUI, which means everything
    ////else has to be done using events. I know its a pain, but this is how u do it
	////Create event, events cant be created normally using new, so you have to do it this way
    wxLogMessageEvent *LogMessageEvent = (wxLogMessageEvent *)wxCreateDynamicObject(wxT("wxLogMessageEvent"));
	////wxLogMessageEvent has a custom member function SetMessage which sets the text to output
    LogMessageEvent->SetMessage(output);
    ////Finally post the event to the frames message handler. Note frame is declared as an extern in the App.h file
	wxPostEvent(frame, *LogMessageEvent);
}

void DeadProxyFrmApp::UpdateClientBox(wxString * identifier, int pos, char op)
{
    wxGUIEvent *UpdateClientBoxEvent = (wxGUIEvent *)wxCreateDynamicObject(wxT("wxGUIEvent"));
    UpdateClientBoxEvent->SetStr1(identifier);
    UpdateClientBoxEvent->SetParam1(pos);
    UpdateClientBoxEvent->SetParam2(op);
    UpdateClientBoxEvent->SetEventType(wxEVT_UPDATE_CLIENT_BOX);
    UpdateClientBoxEvent->SetId(wxUPDATE_CLIENT_BOX_ID);
    wxPostEvent(frame, *UpdateClientBoxEvent);
}

void DeadProxyFrmApp::AddClientToBox(wxString * identifier)
{
    UpdateClientBox(identifier, 0, 0);
}

void DeadProxyFrmApp::EditClientInBox(wxString * identifier, int pos)
{
    UpdateClientBox(identifier, pos, 1);
}

void DeadProxyFrmApp::RemoveClientFromBox(int pos)
{
    UpdateClientBox((wxString*)0, pos, 2);
}

void DeadProxyFrmApp::AddPacketToBox(wxString * identifier)
{
    UpdatePacketBox(identifier, 0, 0);
}

void DeadProxyFrmApp::EditPacketInBox(wxString * identifier, int pos)
{
    UpdatePacketBox(identifier, pos, 1);
}

void DeadProxyFrmApp::RemovePacketFromBox(int pos)
{
    UpdatePacketBox((wxString*)0, pos, 2);
}


void DeadProxyFrmApp::UpdatePacketBox(wxString * identifier, int pos, char op)
{
    wxGUIEvent *UpdatePacketBoxEvent = (wxGUIEvent *)wxCreateDynamicObject(wxT("wxGUIEvent"));
    UpdatePacketBoxEvent->SetStr1(identifier);
    UpdatePacketBoxEvent->SetParam1(pos);
    UpdatePacketBoxEvent->SetParam2(op);
    UpdatePacketBoxEvent->SetEventType(wxEVT_UPDATE_PACKET_BOX);
    UpdatePacketBoxEvent->SetId(wxUPDATE_PACKET_BOX_ID);
    wxPostEvent(frame, *UpdatePacketBoxEvent);
}

void DeadProxyFrmApp::SetPacketString(wxString * packstr)
{
    wxGUIEvent *SetPacketStringEvent = (wxGUIEvent *)wxCreateDynamicObject(wxT("wxGUIEvent"));
    SetPacketStringEvent->SetStr1(packstr);
    SetPacketStringEvent->SetEventType(wxEVT_SET_PACKET_STRING);
    SetPacketStringEvent->SetId(wxSET_PACKET_STRING_ID);
    wxPostEvent(frame, *SetPacketStringEvent);
}

void DeadProxyFrmApp::InitClientSelectInfo(Client::InitSelectInfo * ISI)
{
    wxGUIEvent *InitClientSelectEvent = (wxGUIEvent *)wxCreateDynamicObject(wxT("wxGUIEvent"));
    InitClientSelectEvent->SetParam1((int)ISI);
    InitClientSelectEvent->SetEventType(wxEVT_INIT_CLIENT_SELECT);
    InitClientSelectEvent->SetId(wxINIT_CLIENT_SELECT_ID);
    wxPostEvent(frame, *InitClientSelectEvent);
}

void DeadProxyFrmApp::SetMessageInfo(wxArrayString * MessageInfo)
{
    wxGUIEvent *SetMessageInfoEvent = (wxGUIEvent *)wxCreateDynamicObject(wxT("wxGUIEvent"));
    SetMessageInfoEvent->SetParam1((int)MessageInfo);
    SetMessageInfoEvent->SetEventType(wxEVT_SET_MESSAGE_INFO);
    SetMessageInfoEvent->SetId(wxSET_MESSAGE_INFO_ID);
    wxPostEvent(frame, *SetMessageInfoEvent);
}


void DeadProxyFrmApp::UpdateMessageBox(wxString * identifier, int pos, char op)
{
    wxGUIEvent *UpdateMessageBoxEvent = (wxGUIEvent *)wxCreateDynamicObject(wxT("wxGUIEvent"));
    UpdateMessageBoxEvent->SetStr1(identifier);
    UpdateMessageBoxEvent->SetParam1(pos);
    UpdateMessageBoxEvent->SetParam2(op);
    UpdateMessageBoxEvent->SetEventType(wxEVT_UPDATE_MESSAGE_BOX);
    UpdateMessageBoxEvent->SetId(wxUPDATE_MESSAGE_BOX_ID);
    wxPostEvent(frame, *UpdateMessageBoxEvent);
}

void DeadProxyFrmApp::UpdateChannelBox(wxString * identifier, int pos, char op)
{
    wxGUIEvent *UpdateChannelBoxEvent = (wxGUIEvent *)wxCreateDynamicObject(wxT("wxGUIEvent"));
    UpdateChannelBoxEvent->SetStr1(identifier);
    UpdateChannelBoxEvent->SetParam1(pos);
    UpdateChannelBoxEvent->SetParam2(op);
    UpdateChannelBoxEvent->SetEventType(wxEVT_UPDATE_CHANNEL_BOX);
    UpdateChannelBoxEvent->SetId(wxUPDATE_CHANNEL_BOX_ID);
    wxPostEvent(frame, *UpdateChannelBoxEvent);
}

void DeadProxyFrmApp::AddChannelToBox(wxString * identifier)
{
    UpdateChannelBox(identifier, 0, 0);
}

void DeadProxyFrmApp::RemoveChannelFromBox(int pos)
{
    UpdateChannelBox((wxString*)0, pos, 2);
}

void DeadProxyFrmApp::ClearChannelBox()
{
    UpdateChannelBox((wxString*)0, 0, 3);
}

void DeadProxyFrmApp::AddMessageToBox(wxString * identifier)
{
    UpdateMessageBox(identifier, 0, 0);
}

void DeadProxyFrmApp::ClearMessageBox()
{
    UpdateMessageBox((wxString*)0, 0, 3);
}

void DeadProxyFrmApp::SetMessageBoxArray(wxArrayString * MessageArray)
{
    UpdateMessageBox((wxString*)0, (int)MessageArray, 4);
}

void DeadProxyFrmApp::LogPacket(int sendrecv, unsigned char * buffer, int length)
{
    wxString * output;
    output = new wxString;
    if(sendrecv == 0)
    {
        output->Printf("send\n");
    } else {
        output->Printf("recv\n");
    }
    int rows;
    if(length%16 == 0)
    {
        rows = length / 16;
    } else {
        rows = (length - length%16 + 16)/16;
    }
    for(int i = 0; i < rows; i++)
    {
        for(int ii = 0; ii < 16; ii++)
        {
            if(i * 16 + ii >= length)
            {
                output->Append(wxT("   "));
            } else {
                if(buffer[i * 16 + ii]<16)
                {
                    output->Append(wxT("0"));
                }
                output->Append(wxString::Format("%X ",buffer[i * 16 + ii]));
            }
        }
        output->Append(wxString::Format("   "));
        for(int ii = 0; ii < 16; ii++)
        {
            if(i * 16 + ii >= length)
            {
                break;
            }
            if(buffer[i * 16 + ii] >= 32 && buffer[i * 16 + ii] <= 126)
            {
                output->Append(wxString::Format("%c",buffer[i * 16 + ii]));
            } else {
                output->Append(wxT("."));
            }
        }
        output->Append(wxT("\n"));
    }
    LogMessage(output);
}
